package com.dbumama.market.web.mobile.pay.controller;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.dbumama.market.model.Area;
import com.dbumama.market.model.AuthUserConfig;
import com.dbumama.market.model.BuyerReceiver;
import com.dbumama.market.model.BuyerUser;
import com.dbumama.market.service.api.order.OrderException;
import com.dbumama.market.service.api.order.OrderPayResultDto;
import com.dbumama.market.service.api.order.OrderResultDto;
import com.dbumama.market.service.api.order.OrderService;
import com.dbumama.market.service.api.pay.PayException;
import com.dbumama.market.service.api.pay.PayService;
import com.dbumama.market.web.core.annotation.RouteBind;
import com.dbumama.market.web.core.controller.BaseMobileController;
import com.dbumama.market.web.core.plugin.spring.Inject.BY_NAME;
import com.dbumama.market.web.core.utils.IpKit;
import com.jfinal.kit.StrKit;
import com.weixin.sdk.utils.SignKit;

@RouteBind(path="pay")
public class PayController extends BaseMobileController{
	
	public static Set<String> userTradeSet = new HashSet();

	@BY_NAME
	private OrderService orderService;

	@BY_NAME
	private PayService payService;
	/**
	 * h5 发起支付
	 */
	public void index(){
		String type = getPara("type");
		if(StrKit.notBlank(type)){
			//充值抽奖
			lottery();
		}else{
			  try
		      {
		        Long orderId = getParaToLong("orderId");
		        OrderPayResultDto order = this.orderService.getOrderPayInfo(orderId, getBuyerId());
		        TreeMap<String, Object> params = this.payService.prepareToPay(getOpenId(), order.getTradeNo(), order.getPayFee(), order.getOrderSn(), IpKit.getRealIpV2(getRequest()));
		        rendSuccessJson(params);
		      }
		      catch (OrderException e)
		      {
		        rendFailedJson(e.getMessage());
		      }
		      catch (PayException e)
		      {
		        rendFailedJson(e.getMessage());
		      }
		}
	}
	
	/**
	 * 订单结算
	 */
	public void balance (){
		final String items = getPara("items");
		final Long receiverId = getParaToLong("receiverId");
		setAttr("items", items);
		OrderResultDto orderDto = orderService.balance(getBuyerId(), receiverId, items);
		setAttr("order", orderDto);
    	//查询默认收货地址
		final String sql = "SELECT * FROM "+BuyerReceiver.table+" WHERE buyer_id = ? AND is_default = 1 ";
		BuyerReceiver buyerReceiver=BuyerReceiver.dao.findFirst(sql, getBuyerId());
		if(buyerReceiver != null) {
			Area area=Area.dao.findById(buyerReceiver.getAreaId());
			setAttr("fullName",area.getFullName());
			setAttr("receiver", buyerReceiver);
		}
		render("/pay/jiesuan.html");
	}
	
	  public void card()
	  {
	    Long orderId = getParaToLong("orderId");
	    try
	    {
	      this.payService.payByCard(orderId, getBuyerId());
	      rendSuccessJson();
	    }
	    catch (PayException e)
	    {
	      rendFailedJson(e.getMessage());
	    }
	  }
	
	void lottery () {
		String type = getPara("type");
		int totalMoney = 0;
		
		if("x11".equals(type)){
			totalMoney = 2;
		}else if("x12".equals(type)){
			totalMoney = 5;
		}else if("x13".equals(type)){
			totalMoney = 10;
		}else{
			totalMoney = 0;
		}
		
		if(totalMoney<=0){
			rendFailedJson("提交的金额为0，请重新确认");
			return;
		}
		
		rendFailedJson("请开通企业版");
	}
	public void result()
	{
		this.log.debug("===================支付成功，成功回调");
		String resultXml = null;
		try {
			resultXml = inputStream2String(getRequest().getInputStream());
		} catch (Exception e) {
			e.printStackTrace();
			renderNull();
			return;
		}
		if (StrKit.isBlank(resultXml)) {
			renderNull();
			return;
		}
		Document doc = null;
		try {
			doc = DocumentHelper.parseText(resultXml);
		} catch (DocumentException e) {
			e.printStackTrace();
			renderNull();
			return;
		}
		Element root = doc.getRootElement();

		TreeMap<String, Object> params = new TreeMap();

		List<Element> elements = root.elements();
		String authAppId = "";
		for (Element e : elements) {
			params.put(e.getName(), e.getTextTrim());
			if ("appid".equals(e.getName())) {
				authAppId = e.getTextTrim();
			}
		}

		/*
		 * AuthUserConfig authUser = this.authUserConfigService.getAuthConfig(); if
		 * (authUser == null) { this.log.error("[" + authAppId + "]授权公众号不存在");
		 * renderText(
		 * "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>",
		 * "text/xml"); return; }
		 */
		
		AuthUserConfig authUser = (AuthUserConfig)AuthUserConfig.dao.findFirst("select * from t_auth_user_config");
		String sign = SignKit.sign(params, authUser.getPaySecretKey());
		String tenpaySign = root.elementText("sign").toUpperCase();
		if ((StrKit.isBlank(sign)) || (StrKit.isBlank(tenpaySign)) || (!sign.equals(tenpaySign))) {
			this.log.error("微信支付异步通知签名错误");
			renderText(
					"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>",
					"text/xml");
			return;
		}

		this.log.debug("成功回调，签名正确");

		String tradeNo = (String) params.get("out_trade_no");
		this.log.debug("tradeNo:" + tradeNo);
		String openid = (String) params.get("openid");
		BuyerUser user = BuyerUser.dao.findFirst("select * from t_buyer_user where open_id=? ", openid);
		if (user == null) {
			this.log.error("[" + openid + "] user is null");
			renderText(
					"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>",
					"text/xml");
			return;
		}

		synchronized (userTradeSet) {
			if (userTradeSet.contains(tradeNo + openid)) {
				renderText(
						"<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>",
						"text/xml");
				return;
			}
			userTradeSet.add(tradeNo + openid);
		}
		try {
			if ((StrKit.notBlank(tradeNo)) && (tradeNo.startsWith("l-"))) {
				this.payService.resultLotteryCallback(user, params);
			} else if ((StrKit.notBlank(tradeNo)) && (tradeNo.startsWith("c-"))) {
				this.payService.resultMemberCardCallback(user, params);
			} else
				this.payService.resultOrderCallback(user, params);
		} catch (PayException e) {
			e.printStackTrace();
			this.log.error(e.getMessage());
		} finally {
			userTradeSet.remove(tradeNo + openid);
		}

		renderText("<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>",
				"text/xml");
	}
	
	
}
